/// Extension on the [String]
extension JMStringExtension on String {
  /// JMStringExtension: Capitalize each word inside string.
  ///
  /// Example:
  /// ```dart
  /// 'your name'.capitalize // Your Name
  /// ```
  String get capitalize => split(' ').map((str) => str.capitalizeFirst).join(' ');

  /// JMStringExtension: Uppercase first letter inside string and let the others lowercase.
  ///
  /// Example:
  /// ```dart
  /// 'your name'.capitalizeFirst // Your name
  /// ```
  String get capitalizeFirst => "${this[0].toUpperCase()}${substring(1).toLowerCase()}";

  /// JMStringExtension: Checks if string contains at least one Capital Letter
  bool get hasCapitalLetter => hasMatch(r'[A-Z]');

  bool get is7Z => hasMatch(r'^.+\.7z$');

  bool get isAlphabetOnly => hasMatch(r'^[a-zA-Z]+$');

  bool get isAlphanumeric => hasMatch(r'^[a-zA-Z0-9]+$');

  bool get isAPK => hasMatch(r'^.+\.apk$');

  bool get isBool => this == 'true' || this == 'false';

  bool get isCSV => hasMatch(r'^.+\.csv$');

  bool get isDOC => hasMatch(r'^.+\.doc$');

  bool get isDOCX => hasMatch(r'^.+\.docx$');

  bool get isDouble => double.tryParse(this) != null;

  bool get isEmail => hasMatch(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');

  bool get isGIF => hasMatch(r'^.+\.gif$');

  bool get isGZ => hasMatch(r'^.+\.gz$');

  bool get isHexColor => hasMatch(r'^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$');

  bool get isInt => int.tryParse(this) != null;

  bool get isJPEG => hasMatch(r'^.+\.jpeg$');

  bool get isJPG => hasMatch(r'^.+\.jpg$');

  bool get isLowerCase => hasMatch(r'^[a-z]+$');

  bool get isMP3 => hasMatch(r'^.+\.mp3$');

  bool get isMP4 => hasMatch(r'^.+\.mp4$');

  bool get isMPEG => hasMatch(r'^.+\.mpeg$');

  bool get isMPG => hasMatch(r'^.+\.mpg$');

  bool get isNumeric => double.tryParse(this) != null;

  bool get isNumericOnly => hasMatch(r'^\d+$');

  bool get isPDF => hasMatch(r'^.+\.pdf$');

  bool get isPhoneNumber => hasMatch(r'^[0-9\-\+\s\(\)]{10,20}$');

  bool get isPNG => hasMatch(r'^.+\.png$');

  bool get isPPT => hasMatch(r'^.+\.ppt$');

  bool get isPPTX => hasMatch(r'^.+\.pptx$');

  bool get isRAR => hasMatch(r'^.+\.rar$');

  bool get isRTF => hasMatch(r'^.+\.rtf$');

  bool get isSVG => isEmpty ? false : endsWith(".svg");

  bool get isTAR => hasMatch(r'^.+\.tar$');

  bool get isTXT => hasMatch(r'^.+\.txt$');

  bool get isUpperCase => hasMatch(r'^[A-Z]+$');

  bool get isURL => hasMatch(r'^http(s)?://([\w-]+.)+[\w-]+(/[\w- ./?%&=])?$');

  bool get isValidDate => DateTime.tryParse(this) != null;

  bool get isXLS => hasMatch(r'^.+\.xls$');

  bool get isXLSX => hasMatch(r'^.+\.xlsx$');

  bool get isZIP => hasMatch(r'^.+\.zip$');

  /// JMStringExtension: Remove all whitespace inside string.
  ///
  /// Example:
  /// ```dart
  /// 'your name'.removeAllWhitespace // yourname
  /// ```
  String get removeAllWhitespace => replaceAll(' ', '');

  bool hasMatch(String pattern) => RegExp(pattern).hasMatch(this);

  /// JMStringExtension: Remove 0 end of dot.
  ///
  /// Example:
  /// ```dart
  /// '100.100'.wipeEndZero // 100.1
  /// '100.00'.wipeEndZero // 100
  /// ```
  String get wipeEndZero {
    var res = this;
    if (res.contains('.')) {
      while (true) {
        if (res.endsWith('0')) {
          res = res.substring(0, res.length - 1);
        } else {
          if (res.endsWith('.')) {
            res = res.substring(0, res.length - 1);
          }
          break;
        }
      }
    }
    return res;
  }

  /// JMStringExtension: Thousand format.
  ///
  /// Example:
  /// ```dart
  /// '10000'.thousandsFormat() // 10,000
  /// ```
  String thousandsFormat({int point = 0}) {
    if (isEmpty) return '0';

    String str = this;
    List<String> sub = str.split('.');
    List val = List.from(sub[0].split(''));
    List<String> points = List.from(sub[1].split(''));
    for (int index = 0, i = val.length - 1; i >= 0; index++, i--) {
      if (index % 3 == 0 && index != 0 && i != 1) val[i] = val[i] + ',';
    }

    for (int i = 0; i <= point - points.length; i++) {
      points.add('0');
    }

    if (points.length > point) {
      points = points.sublist(0, point);
    }

    if (points.isNotEmpty) {
      return '${val.join('')}.${points.join('')}';
    } else {
      return val.join('');
    }
  }

  //手机号脱敏
  String get phoneDesensitization {
    if (isNotEmpty) {
      return '${substring(0, 3)}****${substring(length - 4)}';
    } else {
      return this;
    }
  }
}
